package serivces

import (
	"context"
	"encoding/base64"
	"errors"
	"tcp_server/src/common_util"
	"tcp_server/src/config"
	"tcp_server/src/dao"
	"tcp_server/src/models"
)

type UserMessageService struct {
}

func NewUserMessageService() *UserMessageService {
	return &UserMessageService{}
}

// UpdateUserMessageMethod 更新个人信息 1代表更新成功，-1代表 更新失败
func (u *UserMessageService) UpdateUserMessageMethod(args ...interface{}) (interface{}, error) {
	if len(args) < 3 {
		common_util.ErrorLogger.Printf("UpdateUserMessageMethod 方法被调用传入的参数不足，所需为3，传入为: %v", len(args))
		return nil, errors.New("调用UpdateUserMessageMethod 方法所需要参数不足")
	}
	user, err := extractUserMessageFromRequest(args)
	if err != nil {
		return 0, err
	}
	userRedisKey := config.RedisUserBaseMessageKey + user.UserName
	// 先删除缓存
	redisClient := config.Redis
	if err1 := redisClient.Del(context.Background(), userRedisKey).Err(); err1 != nil {
		common_util.ErrorLogger.Printf("删除用户"+user.UserName+"的基本数据redis缓存出现错误:", err1)
	}

	if err2 := dao.UpdateUserBaseMessage(user); err2 != nil {
		common_util.ErrorLogger.Printf("更新数据库出现失败: %v", err2)
		return nil, errors.New("更新数据库出现失败")
	}

	// 二次删，可设置延迟
	if err3 := redisClient.Del(context.Background(), userRedisKey).Err(); err3 != nil {
		common_util.ErrorLogger.Printf("删除用户"+user.UserName+"的基本数据redis缓存出现错误:", err3)
	}

	return 1, nil
}

func (u *UserMessageService) GetUserMessageMethod(args ...interface{}) (interface{}, error) {
	username := args[0].(string)
	var user common_util.RPCUserResponse
	user.Username = username
	// 查询Redis
	redisUserMessageKey := config.RedisUserBaseMessageKey + username
	userRedisData, getRedisErr := config.Redis.HGetAll(context.Background(), redisUserMessageKey).Result()
	if getRedisErr != nil {
		common_util.ErrorLogger.Printf("查询redis缓存的用户个人基本信息出现错误: %v", getRedisErr)
		return nil, errors.New("TCP Server : 查询redis缓存的用户个人基本信息出现错误")
	}
	flag := false
	if nickname, ok := userRedisData["nickname"]; ok {
		user.Nickname = nickname
		flag = true
	}
	if base64Picture, ok := userRedisData["picture"]; ok {
		user.Picture = base64Picture
		flag = true
	}
	if flag {
		user.Code = 1
		return user, nil
	}
	// Redis 不存在则查询数据库
	userSQLResult, err := dao.GetUserBaseMessage(username)
	if err != nil {
		common_util.ErrorLogger.Printf("查询数据库获取用户个人基本信息出现错误: %v", err)
		return nil, errors.New("TCP Server : 查询数据库获取用户个人基本信息出现错误")
	}
	if userSQLResult == nil {
		common_util.ErrorLogger.Printf("未能获取到该用户的基本个人信息， 用户username ： " + username)
		user.Code = 0
		return user, nil
	}
	user.Nickname = userSQLResult.NickName
	user.Picture = base64.StdEncoding.EncodeToString(userSQLResult.Picture)
	user.Code = 1
	// 将用户的数据保存到Redis中去，由于更新会做删除，所以这里不做过期
	if redisSaveErr := config.Redis.HSet(context.Background(), redisUserMessageKey, map[string]interface{}{
		"nickname": userSQLResult.NickName,
		"picture":  user.Picture,
	}).Err(); redisSaveErr != nil {
		common_util.ErrorLogger.Printf("将用户个人基本信息缓存至Redis出现异常: %v", redisSaveErr)
	}
	return user, nil
}

func extractUserMessageFromRequest(args []interface{}) (*models.User, error) {
	username := args[0].(string)
	nickname := args[1].(string)
	// 解析图片字节
	pictureData := args[2].(string)
	picture, err := base64.StdEncoding.DecodeString(pictureData)
	if err != nil {
		return nil, errors.New("图片的base64字符串解码成字节数组出现错误: " + err.Error())
	}
	return &models.User{UserName: username, NickName: nickname, Picture: picture}, nil
}
